package com.tanhua.server.impl;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.RecommendUserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.Visitorsapi;
import com.tanhua.exception.BusinessException;
import com.tanhua.interceptor.UserHolder;
import com.tanhua.model.domain.ErrorResult;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.vo.VisitorsVo;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class movementService {
    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private RecommendUserApi recommendUserApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @DubboReference
    private Visitorsapi visitorsapi;
    @Autowired
    private MqMessageService mqMessageService;

    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        PageResult pr = movementApi.findByUserId(userId, page, pagesize);
        List<Movement> items = (List<Movement>) pr.getItems();
        if (items == null) {
            return pr;
        }
        //循环数据列表
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            //5、一个Movement构建一个Vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos.add(vo);
        }
        //6、构建返回值
        pr.setItems(vos);
        return pr;
    }

    /**
     * 发布动态
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1、判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2、获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3、将文件内容上传到阿里云OSS，获取请求地址
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4、将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(medias);
        //5、调用API完成发布动态
        movementApi.publish(movement);
    }

    /*
     * 查询好友动态
     * */
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        List<Movement> list = movementApi.findFriendMovements(userId, page, pagesize);
        return getPageResult(page, pagesize, list);
    }

    //抽取分页方法
    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> list) {
        //如果为空 返回空PageResult
        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //提取动态发布人的id列表
        //List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //java8方式
        List<Long> userIds = list.stream().map(Movement::getUserId).collect(Collectors.toList());
        //获取发布人详情
        Map<Long, UserInfo> mapinfro = userInfoApi.findByIds(userIds, null);
        //一个Movement构造一个vo对象
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = mapinfro.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                //修复点赞bug，判断hashkey是否存在
                String key = Constants.MOVEMENTS_INTERACT_KEY + movement.getId().toHexString();
                String haskey = Constants.MOVEMENT_LIKE_HASHKEY + UserHolder.getUserId();
                if (redisTemplate.opsForHash().hasKey(key, haskey)) {
                    vo.setHasLiked(1);
                }
                vos.add(vo);
            }
        }
//        List<MovementsVo> vos = list.stream()
//                .filter(c -> mapinfro.get(c.getUserId()) != null)
//                .map(movement -> {
//                    return MovementsVo.init(mapinfro.get(movement.getUserId()), movement);
//                }).collect(Collectors.toList());

        //7、构造PageResult并返回
        return new PageResult(page, pagesize, 0l, vos);
    }

    /*
     *查询推荐动态
     *
     * */
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        List<Movement> list = movementApi.randomMovements(pagesize);

        return getPageResult(page, pagesize, list);
    }

    public MovementsVo findBymovementId(String movementId) {
        System.out.println(movementId);
        Movement movement = movementApi.findBymovementId(movementId);
        if (movement == null) {
            return null;
        }
        UserInfo userInfo = userInfoApi.findById(movement.getUserId());
        MovementsVo movementsVo = MovementsVo.init(userInfo, movement);
        return movementsVo;
    }

    // 谁看过我
    public List<VisitorsVo> queryVisitorsList() {
        //根据用户id查询
        List<Visitors> list = visitorsapi.queryMyVisitors(UserHolder.getUserId());
        //获取看过我的 用户id
        List<Long> visitorUserId = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(visitorUserId, null);
        ArrayList<VisitorsVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            UserInfo userInfo = map.get(visitors.getVisitorUserId());
            if (userInfo != null) {
                VisitorsVo vo = VisitorsVo.init(userInfo, visitors);
                vos.add(vo);
            }
        }
        return vos;
    }
}
